home *** CD-ROM | disk | FTP | other *** search
- #include "Utilities.h"
-
- short gQDVersion; /* major QD version #; 0 for original,
- 1 for color QD, 2 for 32-bit QD */
- short gInitMPDUtils = 0;
- static Rect gWindowPlacementRect;
- static short gSystemVersion; /* System version number */
- static short gAppResRef;
-
- /********************************************************************************
- *
- * Borrowed from DTS Lib
- *
- ********************************************************************************/
-
- #define TopLeft(r) (* (Point *) &(r).top)
- #define BotRight(r) (* (Point *) &(r).bottom)
- enum { kQDOriginal = 0, kQD8Bit, kQD32Bit }; /* For use with gQDVersion */
- #define offsetof(structure,field) ((unsigned long)&((structure *) 0)->field)
-
- typedef Boolean (*TrackControlProcPtr)(ControlHandle ctl, short part, EventRecord *event);
- typedef void (*ScrollProcPtr)(ControlHandle ctl, short part, short oldVal, short newVal);
- typedef void (*DrawControlProcPtr)(ControlHandle ctl);
-
- typedef struct ControlStyleInfo {
- short ctlID;
- TrackControlProcPtr trackProc;
- ScrollProcPtr scrollProc;
- short hArrowVal;
- short vArrowVal;
- short hPageVal;
- short vPageVal;
- DrawControlProcPtr drawControl;
- short fontSize;
- Style fontStyle;
- Str32 font;
- Str63 keyEquivs;
- Str255 balloonHelp;
- } ControlStyleInfo;
- typedef ControlStyleInfo *ControlStyleInfoPtr;
-
- static DrawControlProcPtr gDrawControl;
- static Handle gScrollProc;
- static Handle gPopupProc;
- static Handle gButtonProcs[radioButProc + useWFont + 1];
- static ControlHandle gWhichCtlHit;
- static long gWhichCtlWhen;
- static Boolean gWhichCtlDbl;
- static Boolean gWhichCtlTracking;
-
- Boolean GetCheckOrRadio(DialogPtr dlgPtr, short itemNo)
- {
- short iKind;
- Handle iHandle;
- Rect iRect;
-
- GetDialogItem(dlgPtr, itemNo, &iKind, &iHandle, &iRect);
- return(GetControlValue((ControlHandle)iHandle) != 0);
- }
-
- void ToggleCheck(DialogPtr dlgPtr, short chkItem)
- {
- short iKind;
- Handle iHandle;
- Rect iRect;
-
- GetDialogItem(dlgPtr, chkItem, &iKind, &iHandle, &iRect);
- SetControlValue((ControlHandle) iHandle, !GetControlValue((ControlHandle)iHandle));
- }
-
- void SetCheckOrRadioButton(DialogPtr dlgPtr, short itemNo, short state)
- {
- short iKind;
- Handle iHandle;
- Rect iRect;
-
- GetDialogItem(dlgPtr, itemNo, &iKind, &iHandle, &iRect);
- SetControlValue((ControlHandle)iHandle, state);
- }
-
- char LockHandleHigh(Handle theHandle)
- {
- char hstate;
-
- hstate = HGetState(theHandle);
- MoveHHi(theHandle);
- HLock(theHandle);
- return(hstate);
- }
-
- short GetHexByte(char *cptr)
- {
- short val, i, chr;
-
- for (val = 0, i = 0; i < 2; ++i) {
- chr = cptr[i];
- if (chr == '=') return(cptr[++i]);
- if (chr == '≈') {
- chr = cptr[++i];
- if ((chr >= 'a') && (chr <= 'z')) chr -= 32;
- return(chr);
- }
- if (chr > 'F')
- chr -= 0x20;
- if (chr > '9')
- chr -= ('A' - '9' - 1);
- val = (val << 4) + chr - '0';
- }
- return(val);
- }
-
- void OutlineDialogItem(DialogPtr dlgPtr, short item)
- {
- short iKind;
- Handle iHandle;
- Rect iRect;
-
- GetDialogItem(dlgPtr, item, &iKind, &iHandle, &iRect);
- OutlineControl((ControlHandle) iHandle);
- }
-
- /* Given any control handle, this will draw an outline around it. This is used
- ** for the default button of a window. The extra nice feature here is that
- ** I’ll erase the outline for buttons that are inactive. Seems like there
- ** should be a Toolbox call for getting a control’s hilite state. Since there
- ** isn’t, I have to look into the control record myself. This should be called
- ** for update and activate events.
- **
- ** The method for determining the oval diameters for the roundrect is a little
- ** different than that recommended by Inside Mac. IM I-407 suggests that you
- ** use a hardcoded (16,16) for the diameters. However, this only looks good
- ** for small roundrects. For larger ones, the outline doesn’t follow the inner
- ** roundrect because the CDEF for simple buttons doesn’t use (16,16). Instead,
- ** it uses half the height of the button as the diameter. By using this
- ** formula, too, our outlines look better. */
-
- void OutlineControl(ControlHandle button)
- {
- WindowPtr oldPort;
- Rect theRect;
- PenState curPen;
- short buttonOval;
- RgnHandle oldClip, newClip;
- RGBColor oldrgb;
-
- static RGBColor whitergb = {0xFFFF, 0xFFFF, 0xFFFF};
- static RGBColor grayrgb = {0x8000, 0x8000, 0x8000};
- static RGBColor blackrgb = {0x0000, 0x0000, 0x0000};
-
- if (button) {
- if ((*button)->contrlVis) {
- GetPort(&oldPort);
- SetPort((*button)->contrlOwner);
- GetPenState(&curPen);
- PenNormal();
- PenSize(kButtonFrameSize, kButtonFrameSize);
-
- theRect = (*button)->contrlRect;
- InsetRect(&theRect, kButtonFrameInset, kButtonFrameInset);
- buttonOval = (theRect.bottom - theRect.top) / 2 + 2;
-
- GetClip(oldClip = NewRgn());
- newClip = LocalScreenDepthRegion(4);
- SectRgn(oldClip, newClip, newClip);
- SetClip(newClip);
-
- if (!EmptyRgn(newClip)) {
- GetForeColor(&oldrgb);
- switch ((*button)->contrlHilite) {
- case kCntlActivate:
- RGBForeColor(&blackrgb);
- break;
- case kCntlDeactivate:
- RGBForeColor(&grayrgb);
- break;
- default:
- RGBForeColor(&whitergb);
- break;
- }
- FrameRoundRect(&theRect, buttonOval, buttonOval);
- RGBForeColor(&oldrgb);
- }
-
- DiffRgn(oldClip, newClip, newClip);
- SetClip(newClip);
- if (!EmptyRgn(newClip)) {
- switch ((*button)->contrlHilite) {
- case kCntlActivate:
- PenPat((ConstPatternParam)&qd.black);
- break;
- case kCntlDeactivate:
- PenPat((ConstPatternParam)&qd.gray);
- break;
- default:
- PenPat((ConstPatternParam)&qd.white);
- break;
- }
- FrameRoundRect(&theRect, buttonOval, buttonOval);
- }
-
- SetClip(oldClip);
- DisposeRgn(oldClip);
- DisposeRgn(newClip);
-
- SetPenState(&curPen);
- SetPort(oldPort);
- }
- }
- }
-
- /* Given a dialog ID and a window pointer the dialog relates to, this function
- ** will center the dialog’s rectangle before showing it on the proper screen.
- ** This follows the Apple Human Interface Guidelines for where to place a
- ** centered window on the screen. If the dialog is not closely associated with
- ** another window, pass a nil for the window pointer of the related window. If
- ** you pass a nil, the dialog is simply displayed where the resource
- ** would indicate. */
-
- DialogPtr GetCenteredDialog(short id, DialogPtr storage, WindowPtr relatedWindow, WindowPtr behind)
- {
- DialogTHndl dlogResource;
- DialogPtr dialog;
- Boolean oldVis;
- char hstate;
- OSErr err;
- Rect sizeInfo;
-
- dialog = nil;
- if (!SimpleCanDialog()) {
- dlogResource = (DialogTHndl)GetAppResource('DLOG', id, &err);
- if (dlogResource) {
- hstate = LockHandleHigh((Handle)dlogResource);
- oldVis = (*dlogResource)->visible;
- (*dlogResource)->visible = false;
- dialog = GetNewDialog(id, storage, behind);
- if (dialog) {
- SetRect(&sizeInfo, 0, 0, 0, 0);
- CenterWindow(dialog, relatedWindow, sizeInfo);
- if (oldVis)
- ShowWindow(dialog);
- }
- dlogResource = (DialogTHndl)GetAppResource('DLOG', id, &err);
- if (dlogResource) {
- (*dlogResource)->visible = oldVis;
- HSetState((Handle)dlogResource, hstate);
- }
- }
- }
- return(dialog);
- }
-
- /* Center a window within a particular device. The device to center the window
- ** within is determined by passing a related window. This allows related
- ** windows to be kept on the same device. This is useful if an alert is related
- ** to a specific window, for example. */
-
- Rect CenterWindow(WindowPtr window, WindowPtr relatedWindow, Rect sizeInfo)
- {
- WindowPtr whichDevice;
- Rect deviceRect, oldWindowRect, newWindowRect, contentRect;
- short h, v, hh, vv;
-
- if (!(whichDevice = relatedWindow))
- whichDevice = window;
- /* If we have a window to center against, use the device for that window,
- ** else use the device for the window that is getting centered. */
-
- deviceRect = GetWindowDeviceRectNMB(whichDevice);
- /* We now have the rectangle of the device we want to center within. */
-
- if (!EmptyRect(&gWindowPlacementRect))
- deviceRect = gWindowPlacementRect;
-
- contentRect = GetWindowContentRect(window); /* Get where the window is now. */
- h = hh = contentRect.right - contentRect.left;
- v = vv = contentRect.bottom - contentRect.top;
- if (sizeInfo.left)
- if (h < sizeInfo.left)
- h = sizeInfo.left;
- if (sizeInfo.right)
- if (h > sizeInfo.right)
- h = sizeInfo.right;
- if (sizeInfo.top)
- if (v < sizeInfo.top)
- v = sizeInfo.top;
- if (sizeInfo.bottom)
- if (v > sizeInfo.bottom)
- v = sizeInfo.bottom;
- contentRect.right = contentRect.left + h;
- contentRect.bottom = contentRect.top + v;
-
- oldWindowRect = GetWindowStructureRect(window);
- oldWindowRect.right += (h - hh);
- oldWindowRect.bottom += (v - vv);
- newWindowRect = oldWindowRect;
-
- PositionRectInRect(deviceRect, &newWindowRect, FixRatio(1, 2), FixRatio(1, 3));
- /* Figure out the new window strucRect so we can compare it against
- ** the old strucRect. This will tell us how much to move the window. */
-
- OffsetRect(&contentRect, newWindowRect.left - oldWindowRect.left,
- newWindowRect.top - oldWindowRect.top);
- /* Calculate the new content rect. */
-
- MoveWindow(window, contentRect.left, contentRect.top, false);
- /* Move the window to the new location. */
-
- return(contentRect);
- }
-
- /* Given two rectangles, this function positions the second within the first
- ** one so that it maintains the spacing specified by the horzRatio and
- ** vertRatio parameters. In other words, to center an inner rectangle
- ** hoizontally, but have its center be 1/3 from the top of the outer rectangle,
- ** call this function with horzRatio = FixRatio(1, 2), vertRatio =
- ** FixRatio(1, 3). We use Fixed rather than floating point to avoid
- ** complications when mixing MC68881/non-MC68881 versions of Utilities. */
-
- void PositionRectInRect(Rect outerRect, Rect *innerRect, Fixed horzRatio, Fixed vertRatio)
- {
- short outerRectHeight;
- short outerRectWidth;
- short innerRectHeight;
- short innerRectWidth;
- short yLocation;
- short xLocation;
-
- outerRectHeight = outerRect.bottom - outerRect.top;
- outerRectWidth = outerRect.right - outerRect.left;
-
- innerRectHeight = innerRect->bottom - innerRect->top;
- innerRectWidth = innerRect->right - innerRect->left;
- yLocation = Fix2Long(FixMul(Long2Fix(outerRectHeight - innerRectHeight), vertRatio))
- + outerRect.top;
- xLocation = Fix2Long(FixMul(Long2Fix(outerRectWidth - innerRectWidth), horzRatio))
- + outerRect.left;
-
- innerRect->top = yLocation;
- innerRect->left = xLocation;
- innerRect->bottom = yLocation + innerRectHeight;
- innerRect->right = xLocation + innerRectWidth;
- }
-
- /* Given a window pointer, return the global rectangle that encloses the
- ** content area of the window. */
-
- Rect GetWindowContentRect(WindowPtr window)
- {
- WindowPtr oldPort;
- Rect contentRect;
-
- SetRect(&contentRect, 0, 0, 0, 0);
- if (window) {
- GetPort(&oldPort);
- SetPort(window);
- contentRect = window->portRect;
- LocalToGlobalRect(&contentRect);
- SetPort(oldPort);
- }
-
- return(contentRect);
- }
-
- /* This procedure is used to get the rectangle that surrounds the entire
- ** structure of a window. This is true whether or not the window is visible.
- ** If the window is visible, then it is a simple matter of using the bounding
- ** rectangle of the structure region. If the window is invisible, then the
- ** strucRgn is not correct. To make it correct, then window has to be moved
- ** way off the screen and then made visible. This generates a valid strucRgn,
- ** although it is valid for the position that is way off the screen. It still
- ** needs to be offset back into the original position. Once the bounding
- ** rectangle for the strucRgn is obtained, the window can then be hidden again
- ** and moved back to its correct location. Note that ShowHide is used,
- ** instead of ShowWindow and HideWindow. HideWindow can change the plane of
- ** the window. Also, ShowHide does not affect the hiliting of windows.
- ** Note that using ShowHide to make the window visible has the unfortunate
- ** side-effect of changing the userState rect. Since we make the window
- ** invisible prior to moving it back, userState gets left funky. Due to this,
- ** we have to cache it prior to doing the ShowHide games. */
-
- Rect GetWindowStructureRect(WindowPtr window)
- {
- #define kOffscreenLoc 0x4000
-
- GrafPtr oldPort;
- Rect structureRect, userState;
- Point windowLoc;
-
- SetRect(&structureRect, 0, 0, 0, 0);
-
- if (window) {
-
- if (((WindowPeek)window)->visible)
- structureRect = (*(((WindowPeek)window)->strucRgn))->rgnBBox;
-
- else {
- GetPort(&oldPort);
- SetPort(window);
- windowLoc = GetGlobalTopLeft(window);
- if (((WindowPeek)window)->spareFlag)
- userState = (*(WStateDataHandle)(((WindowPeek)window)->dataHandle))->userState;
- MoveWindow(window, kOffscreenLoc, kOffscreenLoc, false);
- ShowHide(window, true);
- structureRect = (*(((WindowPeek)window)->strucRgn))->rgnBBox;
- ShowHide(window, false);
- MoveWindow(window, windowLoc.h, windowLoc.v, false);
- if (((WindowPeek)window)->spareFlag)
- (*(WStateDataHandle)(((WindowPeek)window)->dataHandle))->userState = userState;
- SetPort(oldPort);
- OffsetRect(&structureRect, windowLoc.h - kOffscreenLoc, windowLoc.v - kOffscreenLoc);
- }
- }
-
- return(structureRect);
- }
-
- /* Given a window, this will return the top left point of the window’s port in
- ** global coordinates. Something this doesn’t include is the window’s drag
- ** region (or title bar). This returns the top left point of the window’s
- ** content area only. */
-
- Point GetGlobalTopLeft(WindowPtr window)
- {
- GrafPtr oldPort;
- Point globalPt;
-
- GetPort(&oldPort);
- SetPort(window);
- globalPt = TopLeft(window->portRect);
- LocalToGlobal(&globalPt);
- SetPort(oldPort);
- return(globalPt);
- }
-
- void LocalToGlobalRect(Rect *aRect)
- {
- LocalToGlobal(&TopLeft(*aRect));
- LocalToGlobal(&BotRight(*aRect));
- }
-
- OSErr SimpleCanDialog(void)
- {
- OSErr err;
- ProcessSerialNumber cpsn, fpsn;
- Boolean procsSame;
-
- err = noErr;
- if (gSystemVersion >= 0x0700) {
- err = AEInteractWithUser(kAEDefaultTimeout, nil, nil);
- /* Ask the AppleEvent Manager if we can come forward */
- GetCurrentProcess(&cpsn); /* We may have been moved to the front. */
- GetFrontProcess(&fpsn);
- SameProcess(&cpsn, &fpsn, &procsSame);
- }
-
- return(err);
- }
-
- /* GetAppResource gets a resource from the application's resource file by
- ** resource ID. */
-
- Handle GetAppResource(ResType theType, short theID, OSErr *err)
- {
- short savedResFile;
- Handle returnHandle;
-
- savedResFile = CurResFile();
- UseResFile(gAppResRef);
- returnHandle = Get1Resource(theType, theID);
- if (err) *err = ResError();
- UseResFile(savedResFile);
- return(returnHandle);
- }
-
- RgnHandle LocalScreenDepthRegion(short depth)
- {
- RgnHandle retRgn;
- Point pt;
-
- retRgn = ScreenDepthRegion(depth);
-
- pt.h = pt.v = 0;
- GlobalToLocal(&pt);
- OffsetRgn(retRgn, pt.h, pt.v);
-
- return(retRgn);
- }
-
- RgnHandle ScreenDepthRegion(short depth)
- {
- RgnHandle retRgn, tmpRgn;
- GDHandle device;
- PixMapHandle pmap;
- Rect rct;
- GrafPtr mainPort;
-
- retRgn = NewRgn();
-
- if (gQDVersion == kQDOriginal) {
- if (depth == 1) {
- GetWMgrPort(&mainPort);
- rct = mainPort->portRect;
- RectRgn(retRgn, &rct);
- }
- }
- else {
- tmpRgn = NewRgn();
- for (device = GetDeviceList(); device; device = GetNextDevice(device)) {
- if (
- (TestDeviceAttribute(device, screenDevice)) &&
- (TestDeviceAttribute(device, screenActive))
- ) {
- pmap = (*device)->gdPMap;
- if ((*pmap)->pixelSize >= depth) {
- rct = (*device)->gdRect;
- RectRgn(tmpRgn, &rct);
- UnionRgn(retRgn, tmpRgn, retRgn);
- }
- }
- }
- DisposeRgn(tmpRgn);
- }
-
- return(retRgn);
- }
-
- /* Given a window pointer, find the device that contains most of the window
- ** and return the device's bounding rectangle. If this device is the main
- ** device, then remove the menubar area from the rectangle. */
-
- Rect GetWindowDeviceRectNMB(WindowPtr window)
- {
- Rect deviceRect, tempRect;
-
- SetRect(&deviceRect, 0, 0, 0, 0);
-
- if (window) {
- deviceRect = GetWindowDeviceRect(window);
- tempRect = GetMainScreenRect();
- if (EqualRect(&deviceRect, &tempRect))
- deviceRect.top += GetMBarHeight();
- }
-
- return(deviceRect);
- }
-
- Rect GetMainScreenRect(void)
- {
- GDHandle mainDevice;
- GrafPtr mainPort;
-
- if (gQDVersion > kQDOriginal) {
- mainDevice = GetMainDevice();
- return((*mainDevice)->gdRect);
- }
- else {
- GetWMgrPort(&mainPort);
- return(mainPort->portRect);
- }
- }
-
- /* Given a window pointer, find the device that contains most of the window
- ** and return the device's bounding rectangle. */
-
- Rect GetWindowDeviceRect(WindowPtr window)
- {
- if (gQDVersion > kQDOriginal) {
- GDHandle WindowDeviceHandle = GetRectDevice(GetWindowStructureRect(window));
- return((*WindowDeviceHandle)->gdRect);
- } else {
- return(GetMainScreenRect());
- }
- }
-
- /* Find the greatest overlap device for the given global rectangle. */
-
- GDHandle GetRectDevice(Rect globalRect)
- {
- long area, maxArea;
- GDHandle device, deviceToReturn;
- Rect intersection;
-
- deviceToReturn = GetMainDevice(); /* Use as default choice. */
- maxArea = 0;
-
- for (device = GetDeviceList(); device; device = GetNextDevice(device)) {
- if (TestDeviceAttribute(device, screenDevice)
- && TestDeviceAttribute(device, screenActive)
- && SectRect(&globalRect, &((*device)->gdRect), &intersection)) {
- area = ((long)(intersection.right - intersection.left)) *
- ((long)(intersection.bottom - intersection.top));
- if (area > maxArea) {
- deviceToReturn = device;
- maxArea = area;
- }
- }
- }
- return(deviceToReturn);
- }
-
- void DoDraw1Control(ControlHandle ctl, Boolean scrollBarsOnly)
- {
- WindowPtr window, oldPort;
- Rect rct, srct;
- Point org;
- RgnHandle oldClip, newClip;
- Boolean didPopup;
-
- window = (*ctl)->contrlOwner;
- rct = (*(window->visRgn))->rgnBBox;
- srct = (*(window->clipRgn))->rgnBBox;
- SectRect(&rct, &srct, &srct);
-
- rct = (*ctl)->contrlRect;
- InsetRect(&rct, -4, -4); /* Enclose possible control adornments. */
- SectRect(&rct, &srct, &srct);
- if (EmptyRect(&srct))
- if (!(window->picSave))
- return;
-
- if (IsScrollBar(ctl)) {
- if (((WindowPeek)window)->hilited)
- Draw1Control(ctl);
- else {
- if ((*ctl)->contrlVis) {
- GetPort(&oldPort);
- SetPort(window);
- rct = (*ctl)->contrlRect;
- FrameRect(&rct);
- InsetRect(&rct, 1, 1);
- EraseRect(&rct);
- SetPort(oldPort);
- }
- }
- }
- else {
- if (!scrollBarsOnly) {
- UseControlStyle(ctl);
- didPopup = false;
- if (gPopupProc) { /* The popup control does not handle negative coords. */
- if (StripAddress((*ctl)->contrlDefProc) == StripAddress(gPopupProc)) {
- didPopup = true;
- GetPort(&oldPort);
- SetPort(window);
- GetClip(oldClip = NewRgn()); /* We draw it once, so that internals */
- SetRect(&srct, 0, 0, 0, 0); /* are fixed up. We don't want to show */
- ClipRect(&srct); /* a flash though. */
-
- RectRgn(newClip = NewRgn(), &(window->portRect));
- org.h = window->portRect.left;
- org.v = window->portRect.top;
- SetOrigin(0, 0);
-
- OffsetRect(&((*ctl)->contrlRect), -org.h, -org.v); /* Completely clipped out. */
- Draw1Control(ctl); /* Just to fix internals. */
-
- SectRgn(newClip, oldClip, newClip);
- OffsetRgn(newClip, -org.h, -org.v);
- SetClip(newClip);
- Draw1Control(ctl); /* Now really draw it. */
-
- OffsetRect(&((*ctl)->contrlRect), org.h, org.v);
- SetOrigin(org.h, org.v);
- SetClip(oldClip);
- DisposeRgn(newClip);
- DisposeRgn(oldClip);
-
- SetPort(oldPort);
- }
- }
- if (!didPopup) {
- if ((*ctl)->contrlVis) {
- if (gDrawControl)
- (*gDrawControl)(ctl);
- else
- Draw1Control(ctl);
- }
- }
- UseControlStyle(nil);
- if (GetControlValue(ctl) == 1) {
- if (GetButtonVariant(ctl) == pushButProc)
- OutlineControl(ctl);
- }
- }
- }
- }
-
- void ShowStyledControl(ControlHandle ctl)
- {
- Boolean didPopup;
- WindowPtr oldPort, window;
- RgnHandle oldClip, newClip;
- Point org;
- Rect srct;
-
- if (!(*ctl)->contrlVis) {
-
- didPopup = false;
- if (gPopupProc) { /* The popup control does not handle negative coords. */
- if (StripAddress((*ctl)->contrlDefProc) == StripAddress(gPopupProc)) {
- didPopup = true;
- GetPort(&oldPort);
- SetPort(window = (*ctl)->contrlOwner);
- GetClip(oldClip = NewRgn()); /* We draw it once, so that internals */
- SetRect(&srct, 0, 0, 0, 0); /* are fixed up. We don't want to show */
- ClipRect(&srct); /* a flash though. */
-
- RectRgn(newClip = NewRgn(), &(window->portRect));
- org.h = window->portRect.left;
- org.v = window->portRect.top;
- SetOrigin(0, 0);
-
- UseControlStyle(ctl);
- OffsetRect(&((*ctl)->contrlRect), -org.h, -org.v); /* Completely clipped out. */
- ShowControl(ctl); /* Just to fix internals. */
- Draw1Control(ctl);
-
- SectRgn(newClip, oldClip, newClip);
- OffsetRgn(newClip, -org.h, -org.v);
- SetClip(newClip);
- Draw1Control(ctl); /* Now really show it. */
- UseControlStyle(nil);
-
- OffsetRect(&((*ctl)->contrlRect), org.h, org.v);
- SetOrigin(org.h, org.v);
- SetClip(oldClip);
- DisposeRgn(newClip);
- DisposeRgn(oldClip);
-
- SetPort(oldPort);
- }
- }
-
- if (!didPopup) {
- (*ctl)->contrlVis = 255;
- DoDraw1Control(ctl, false);
- }
- }
- }
-
- void UseControlStyle(ControlHandle ctl)
- {
- WindowPtr oldPort;
- short fnum;
- ControlStyleInfo cinfo;
- static short txFont, txSize;
- static Style txFace;
- static WindowPtr ctlWindow;
-
- if (!ctl) {
- gDrawControl = nil;
- if (ctlWindow) {
- GetPort(&oldPort);
- SetPort(ctlWindow);
- TextFont(txFont);
- TextSize(txSize);
- TextFace(txFace);
- SetPort(oldPort);
- }
- return;
- }
-
- ctlWindow = nil;
- if (GetControlStyle(ctl, &cinfo)) {
- gDrawControl = cinfo.drawControl;
- if (GetControlVariant(ctl) & useWFont) {
- GetPort(&oldPort);
- SetPort(ctlWindow = (*ctl)->contrlOwner);
- txFont = ctlWindow->txFont;
- txSize = ctlWindow->txSize;
- txFace = ctlWindow->txFace;
- TextFace(cinfo.fontStyle);
- fnum = systemFont;
- if (cinfo.font[0])
- GetFNum(cinfo.font, &fnum);
- TextFont(fnum);
- TextSize(cinfo.fontSize);
- SetPort(oldPort);
- }
- }
- }
-
- Boolean GetControlStyle(ControlHandle ctl, void *cinfo)
- {
- short clen, tlen, ofst, ofst2, ofst3;
- Ptr ptr;
-
- clen = GetHandleSize((Handle)ctl);
- tlen = (*ctl)->contrlTitle[0];
- ofst = offsetof(ControlRecord,contrlTitle) + tlen + 1;
- if (clen < ofst + sizeof(short)) return(false);
-
- if (cinfo) {
- ptr = (Ptr)*ctl;
- BlockMove(ptr + ofst, (Ptr)cinfo, clen - ofst);
- ptr = (Ptr)cinfo;
- ofst = offsetof(ControlStyleInfo,font); /* font */
- ofst2 = ofst + ptr[ofst] + 1; /* keyEquivs */
- ofst3 = ofst2 + ptr[ofst2] + 1; /* balloonHelp */
- BlockMove(ptr + ofst3, ptr + offsetof(ControlStyleInfo,balloonHelp), ptr[ofst3] + 1);
- BlockMove(ptr + ofst2, ptr + offsetof(ControlStyleInfo,keyEquivs), ptr[ofst2] + 1);
- }
-
- return(true);
- }
-
- Boolean IsScrollBar(ControlHandle ctl)
- {
- Rect dummy;
- ControlHandle dummyCtl;
-
- if (!ctl) return(false);
-
- if (!gScrollProc) {
- SetRect(&dummy, 0, 0, 16, 100);
- dummyCtl = NewControl((*ctl)->contrlOwner, &dummy, (ConstStr255Param)"\p",
- false, 1, 0, 1, scrollBarProc, 0L);
- if (dummyCtl) {
- gScrollProc = (*dummyCtl)->contrlDefProc;
- DisposeControl(dummyCtl);
- }
- }
-
- return(StripAddress((*ctl)->contrlDefProc) == StripAddress(gScrollProc));
- /* The handle may be locked, which means that the hi-bit
- ** may be on, thus invalidating the compare. Dereference the
- ** handles to get rid of this possibility. */
- }
-
- /* This function returns which kind of button the control is. This does more
- ** than GetCVariant in that it makes sure that the control is actually a
- ** button. It does this by comparing the defProc against the known defProc
- ** for the various button types. For 7.0, there is only one defProc for all
- ** variants, but for pre-7.0, there is one defProc value for each variant.
- ** The method below handles either case. */
-
- short GetButtonVariant(ControlHandle ctl)
- {
- short i;
- Rect dummy;
- ControlHandle dummyCtl;
-
- if (ctl) {
-
- /*
- if (gGetButtonVariant) {
- stop = false;
- i = (*gGetButtonVariant)(ctl, &stop);
- if (i >= 0) return(i);
- if (stop) return(-1);
- }
- */
-
- for (i = pushButProc; i <= radioButProc + useWFont; ++i) {
- if (i == radioButProc + 1)
- i = pushButProc + useWFont;
- if (!gButtonProcs[i]) {
- SetRect(&dummy, 0, 0, 0, 0);
- dummyCtl = NewControl((*ctl)->contrlOwner, &dummy, (ConstStr255Param)"\p",
- false, 1, 0, 1, i, 0L);
- if (dummyCtl) {
- gButtonProcs[i] = (*dummyCtl)->contrlDefProc;
- DisposeControl(dummyCtl);
- }
- }
- if (StripAddress((*ctl)->contrlDefProc) == StripAddress(gButtonProcs[i]))
- return(GetControlVariant(ctl) & (0xFFFF - useWFont));
- /* The handle may be locked, which means that the hi-bit
- ** may be on, thus invalidating the compare. Dereference the
- ** handles to get rid of this possibility. */
- }
- }
-
- return(-1);
- }
-
- Boolean WhichControl(Point mouseLoc, long when, WindowPtr window, ControlHandle *ctlHit)
- {
- Boolean found;
- Rect rct;
- ControlHandle ctl, lastCtl;
- static ControlHandle lastWhenCtl;
-
- gWhichCtlTracking = false;
-
- found = false;
- lastCtl = nil;
-
- if (ctlHit)
- *ctlHit = nil;
-
- if (window) {
- ctl = ((WindowPeek)window)->controlList;
- while (ctl) {
- if ((*ctl)->contrlVis) {
- rct = (*ctl)->contrlRect;
- if (PtInRect(mouseLoc, &rct)) {
- found = true; /* Return the last hit in the linked list, as */
- lastCtl = ctl; /* it is drawn last, and therefore on top. */
- }
- }
- ctl = (*ctl)->nextControl;
- }
- }
-
- if (ctlHit)
- *ctlHit = lastCtl;
-
- gWhichCtlDbl = false;
- if (when) {
- gWhichCtlHit = lastWhenCtl;
- lastWhenCtl = lastCtl;
- if (gWhichCtlHit == lastCtl)
- if (when < gWhichCtlWhen + 30)
- gWhichCtlDbl = true;
- gWhichCtlWhen = when;
- }
- gWhichCtlHit = lastCtl;
-
- return(found);
- }
-
- /* Check to see if a given trap is implemented. */
-
- short NumToolboxTraps(void)
- {
- if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- return(0x200);
- else
- return(0x400);
- }
-
- TrapType GetTrapType(short theTrap)
- {
- /* OS traps start with A0, Tool with A8 or AA. */
- if ((theTrap & 0x0800) == 0) /* per D.A. */
- return(OSTrap);
- else
- return(ToolTrap);
- }
-
- Boolean TrapExists(short theTrap)
- {
- TrapType theTrapType;
-
- theTrapType = GetTrapType(theTrap);
- if ((theTrapType == ToolTrap) && ((theTrap &= 0x07FF) >= NumToolboxTraps()))
- theTrap = _Unimplemented;
-
- return(NGetTrapAddress(_Unimplemented, ToolTrap) != NGetTrapAddress(theTrap, theTrapType));
- }
-
- void InitMPDUtils(void)
- {
- long gestaltResult;
-
- if (!gInitMPDUtils) {
-
- if (Gestalt(gestaltSystemVersion, &gestaltResult) == noErr)
- gSystemVersion = gestaltResult;
- else gSystemVersion = 0;
-
- /* We only concern ourselves with the major QD version number
- ** 0 for original QD, 1 for 8-bit color QD, and 2 for 32-bit QD. */
-
- if (Gestalt(gestaltSystemVersion, &gestaltResult) == noErr)
- gQDVersion = gestaltResult;
- else gQDVersion = 0;
- gQDVersion = (gQDVersion >> 8) & 0xFF;
-
- gAppResRef = CurResFile(); /* returns refNum of .rsrc file */
-
- gInitMPDUtils = true;
- }
- }
-